﻿using System;
using System.Collections.ObjectModel;
using System.Device.Location;
using System.Windows;
using CustomerList.Model;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Phone.Tasks;
using MyMeetup.Entities;
using MyMeetup.Helpers;

namespace MyMeetup.ViewModels
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class EventPageViewModel : ViewModelBase
    {

        private DataService _dataService;
        private INavigationService _navigationService;
       
        public Event Model { get; private set; }
       
        public RelayCommand<PhotoResult> PostPhotoCommand { get; private set; } 
        public RelayCommand LoadedCommand { get; private set; }
        public RelayCommand RsvpYesCommand { get; private set; }
        public RelayCommand RsvpNoCommand { get; private set; }
        public RelayCommand<Rsvp> MemberPageCommand { get; private set; }
        public RelayCommand AddGuest { get; private set; }
        public RelayCommand RemoveGuest { get; private set; }


        /// <summary>
        /// Initializes a new instance of the EventPageViewModel class.
        /// </summary>
        public EventPageViewModel()
        {
            _dataService = new DataService();
            _navigationService = new NavigationService();

            PostPhotoCommand = new RelayCommand<PhotoResult>(PostPhoto);
            LoadedCommand = new RelayCommand(LoadPage);
            RsvpYesCommand = new RelayCommand(SubmitRsvpYes);
            RsvpNoCommand = new RelayCommand(SubmitRsvpNo);

            MemberPageCommand = new RelayCommand<Rsvp>(GetMemberProfile);
            AddGuest = new RelayCommand(IncrementGuestCount);
            RemoveGuest = new RelayCommand(DecrementGuestCount);

            Messenger.Default.Register<PropertyChangedMessage<Event>>(this,
                                                                         (action) => UpdateEvent(action.NewValue));
        }
        
         private void LoadPage()
         {
             _dataService.GetEventAttendees(Model.id, (x) => Attendees = x, ResponseHelper.ErrorCallback);
             _dataService.GetEventPhotos(Model.id, (x) => Photos = x, ResponseHelper.ErrorCallback);
             GetReviews();
         }

      

        private void PostPhoto(PhotoResult photo)
        {
            int idx = photo.OriginalFileName.LastIndexOf('\\');
            string filename = photo.OriginalFileName.Substring(idx);

            _dataService.UploadPhotoToEvent(Model.id, filename, photo.ChosenPhoto, GetPhoto, ResponseHelper.ErrorCallback);

        }



         private void GetPhoto(long photoId)
         {
             _dataService.GetPhoto(photoId, (x) => AddPhotoToAlbum(x), ResponseHelper.ErrorCallback);
         }

         private void AddPhotoToAlbum(Photo photo)
         {
             Photos.Insert(0, photo);
         }





         private void SubmitRsvpYes()
         {
             SubmitRsvp(RSVPType.Yes);
         }

         private void SubmitRsvpNo()
         {
             SubmitRsvp(RSVPType.No);
         }

         private void SubmitRsvp(RSVPType response)
         {
             var rsvpHelper = new RsvpHelper(_dataService, _navigationService);
             rsvpHelper.SubmitRsvp(Model.id, response, MyGuests, Comments, (rsvpResponse) => Rsvp = rsvpResponse.response);
         }


        private void GetReviews()
        {
             //if (Model.GetDate() != DateTime.MinValue && Model.GetDate() > DateTime.Now)
            _dataService.GetEventReviews(Model.id, (x) => CurrentEventRatings = x, ResponseHelper.ErrorCallback);
        }

        private void GetMemberProfile(object selectedAttendee)
        {
            if (LicenseHelper.IsTrial())
            {
                _navigationService.NavigateTo(new Uri("/BuyNow.xaml", UriKind.Relative));
                return;
            }
            
            if(Model.self == null)
                _dataService.GetMember(SelectedAttendee.member.MemberId, (x) => CurrentMember = new ProfileAdapter(x), ResponseHelper.ErrorCallback);
            else
                _dataService.GetMemberProfile(SelectedAttendee.member.MemberId, Model.group.id, (x) => CurrentMember = x, ResponseHelper.ErrorCallback);
        
            GoToMemberPage();
        }

        private void GoToMemberPage()
        {
 
            _navigationService.NavigateTo(new Uri("/MemberPage.xaml", UriKind.Relative));
            
        }

        private void UpdateEvent(Event newEvent)
        {
            if (newEvent == null) return;
            Model = newEvent;
        }

        private void IncrementGuestCount()
        {
            if (MyGuests != Model.rsvp_rules.guest_limit)
                MyGuests++;
        }

        private void DecrementGuestCount()
        {
            if (MyGuests > 0) MyGuests--;
        }




        /// <summary>
        /// The <see cref="Rsvp" /> property's name.
        /// </summary>
        public const string RsvpPropertyName = "Rsvp";

       //private string _rsvp = "none";

        /// <summary>
        /// Gets the Rsvp property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string Rsvp
        {
            get
            {
                if (Model.self != null && Model.self.rsvp != null)
                    return Model.self.rsvp.response;
                else
                    return "none";
            }

            set
            {
                if (Model.self.rsvp.response == value)
                {
                    return;
                }

                var oldValue = Model.self.rsvp.response;
                Model.self.rsvp.response = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(RsvpPropertyName);

            }
        }

        public Visibility PushPinVisibility
        {
            get { return Model.venue == null ? Visibility.Collapsed : Visibility.Visible; }
        }

        public int Zoom
        {
            get
            {
                return Model.venue != null ? 12 : 2;
            }
        }

        public GeoCoordinate MapCenter
        {
            get
            {
                return Model.venue != null
                           ? new GeoCoordinate(Model.venue.lat, Model.venue.lon)
                           : new GeoCoordinate(0, 0);
            }
        }



        /// <summary>
        /// The <see cref="CurrentMember" /> property's name.
        /// </summary>
        public const string CurrentMemberPropertyName = "CurrentMember";

        private IProfile _currentMember;

        /// <summary>
        /// Gets the CurrentMember property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public IProfile CurrentMember
        {
            get
            {
                return _currentMember;
            }

            set
            {
                if (_currentMember == value)
                {
                    return;
                }

                var oldValue = _currentMember;
                _currentMember = value;

                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                RaisePropertyChanged(CurrentMemberPropertyName, oldValue, value, true);
            }
        }



        /// <summary>
        /// The <see cref="Comments" /> property's name.
        /// </summary>
        public const string CommentsPropertyName = "Comments";

        private string _comments = "";

        /// <summary>
        /// Gets the Comments property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string Comments
        {
            get
            {
                return _comments;
            }

            set
            {
                if (_comments == value)
                {
                    return;
                }

                _comments = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(CommentsPropertyName);
            }
        }


        /// <summary>
        /// The <see cref="MyGuests" /> property's name.
        /// </summary>
        public const string MyGuestsPropertyName = "MyGuests";

        private int _myGuests = 0;

        /// <summary>
        /// Gets the MyGuests property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public int MyGuests
        {
            get
            {
                return _myGuests;
            }

            set
            {
                if (_myGuests == value)
                {
                    return;
                }

                var oldValue = _myGuests;
                _myGuests = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(MyGuestsPropertyName);
            }
        }


    

        /// <summary>
        /// The <see cref="CurrentEventRatings" /> property's name.
        /// </summary>
        public const string CurrentEventRatingsPropertyName = "CurrentEventRatings";

        private ObservableCollection<EventReview> _currentEventRatings;

        /// <summary>
        /// Gets the CurrentEventRatings property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<EventReview> CurrentEventRatings
        {
            get
            {
                return _currentEventRatings;
            }

            set
            {
                if (_currentEventRatings == value)
                {
                    return;
                }

                var oldValue = _currentEventRatings;
                _currentEventRatings = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(CurrentEventRatingsPropertyName);

                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                //RaisePropertyChanged(CurrentEventRatingsPropertyName, oldValue, value, true);
            }
        }

        /// <summary>
        /// The <see cref="SelectedAttendee" /> property's name.
        /// </summary>
        public const string SelectedAttendeePropertyName = "SelectedAttendee";

        private Rsvp _selectedAttendee;

        /// <summary>
        /// Gets the SelectedAttendee property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public Rsvp SelectedAttendee
        {
            get
            {
                return _selectedAttendee;
            }

            set
            {
                if (_selectedAttendee == value)
                {
                    return;
                }

                var oldValue = _selectedAttendee;
                _selectedAttendee = value;


                // Update bindings, no broadcast
                RaisePropertyChanged(SelectedAttendeePropertyName);

                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                //RaisePropertyChanged(SelectedAttendeePropertyName, oldValue, value, true);
            }
        }

        /// <summary>
        /// The <see cref="Attendees" /> property's name.
        /// </summary>
        public const string AttendeesPropertyName = "Attendees";

        private ObservableCollection<Rsvp> _attendees = new ObservableCollection<Rsvp>();

        /// <summary>
        /// Gets the Attendees property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<Rsvp> Attendees
        {
            get
            {
                return _attendees;
            }

            set
            {
                if (_attendees == value)
                {
                    return;
                }

                var oldValue = _attendees;
                _attendees = value;


                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                RaisePropertyChanged(AttendeesPropertyName, oldValue, value, true);
            }
        }

        /// <summary>
        /// The <see cref="Photos" /> property's name.
        /// </summary>
        public const string PhotosPropertyName = "Photos";

        private ObservableCollection<Photo> _photos = new ObservableCollection<Photo>();

        /// <summary>
        /// Gets the Photos property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<Photo> Photos
        {
            get
            {
                return _photos;
            }

            set
            {
                if (_photos == value)
                {
                    return;
                }

                var oldValue = _photos;
                _photos = value;


                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                RaisePropertyChanged(PhotosPropertyName, oldValue, value, true);

            }
        }

        
    }
}